package interceptor

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"strconv"
	"time"
	"ylb/config"
	"ylb/tool"
	"ylb/vo"
)

//限制登录,禁止时间五分钟
func LimitLogin() gin.HandlerFunc {
	return func(context *gin.Context) {
		connection := tool.GetRedisConnection()
		defer connection.Close()

		//此处会消耗body参数
		var user vo.UserLoginVo
		context.BindJSON(&user)
		//加入context，以便login方法可以取值
		context.Set("userVo", user)

		key := "limitLogin:" + user.Username
		//redis找key
		n, err := connection.Get(key).Result()
		if err == nil {
			//该用户登录过，且登录失败 n 次
			fmt.Println(user.Username + "登录过 " + n)
			//如果 n == MAX_LOGIN_NUMBER,拒绝登录，且该key设置过期时间为 LOGIN_LIMIT_TIME
			atoi, err := strconv.Atoi(n)
			if err != nil {
				fmt.Println(err)
			}
			//拒绝
			if atoi >= config.MAX_LOGIN_NUMBER {
				if atoi == config.MAX_LOGIN_NUMBER {
					//使得value>MAX_LOGIN_NUMBER,防止重复设置过期时间，造成无限期限制,同时设置过期时间
					connection.Set(key, atoi+1, config.LOGIN_LIMIT_TIME*time.Second)
					fmt.Println(" 限制 【" + user.Username + "】 登录....")

				}

				//已经被限制了，直接返回剩余时间
				result, _ := connection.TTL(key).Result()
				context.JSON(http.StatusOK, tool.Response(config.LIMIT_LOGIN_CODE, "限制登录", gin.H{
					"expire": result,
				}))
				context.Abort()
				return
			}

		} else {
			fmt.Println(user.Username + " 未登录过")
			//从来没登录过
			connection.Set(key, 0, config.LOGIN_LIMIT_TIME*time.Second)
		}

		context.Next()
		//如果登录失败,次数加一
		num, exists := context.Get("loginCode")
		if exists {
			if num == config.LOGIN_SUCCESS_CODE {
				//登录成功,删除key
				connection.Del(key)
			} else if num == config.LOGIN_FAILED_CODE {
				//登录失败,key++
				connection.Incr(key)
			}
		}

	}
}
